/***********************************************************
 *  CCoremain.c
 *
 *  Created on: 2009/8/05
 *  Author: 李、鄧、呉、陳、ト
 *  CopyRight: CBS tech
 *  役割り：Coreの外部関数
 *  作り：新規
 ***********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include "../coredef.h"
#include "../cc/cc.h"
/*------------------------------------------------------*/
/* ローカル常数を宣言										*/
/*------------------------------------------------------*/
#define MAX_IDENT_BUF_LEN    (1024)
#define IS_ILLEGAL_SIZE( s4_Num ) (( s4_Num <= 0 ) || ( s4_Num != 1 && s4_Num != 2 && s4_Num%4 != 0 ))
/*------------------------------------------------------*/
/* ローカルRAMを宣言                                      						*/
/*------------------------------------------------------*/





static struct _OPTION_KEYWORD
{
	PSZ  pszKey;
	UCHAR hasParam;
	U2   u2Id;
}stOptionKey[] =
{

		{ "-compiler",        1, OPTID_CMPLKIND},
		{ "-ptrdiff_t",       1, OPTID_PTRDIFF_TYPE},
		{ "-size_t",        1, OPTID_SIZEOF_TYPE},
		{ "-enumtype",       1, OPTID_ENUMTYPE},
		{ "-char_unsigned",    0,    OPTID_CHAR_UNSIGNED},
		{ "-unsigned_bitfield",  0,      OPTID_BIT_UNSIGNED},
		{ "-signed_bitfield",     0,   OPTID_BIT_SIGNED},
		{ "-pointer_near_far",     0,   OPTID_NEARFAR},
		{ "-overflow_shift_remainder", 0,       OPTID_SHIFT_BITNUM_REMAINDER},
		{ "-overflow_shift_all",   0,     OPTID_SHIFT_BITNUM_ALL},
		{ "-arith_shift",     0,   OPTID_SHIFT_KIND_ARITH},
		{ "-logical_shift",    0,    OPTID_SHIFT_KIND_LOGICAL},
		{ "-signed_modulo",    0,    OPTID_MODULO_SIGNED},
		{ "-unsigned_modulo",   0,     OPTID_MODULO_UNSIGNED},
		{ "-break_ppnum",      0,  OPTID_BREAK_PPNUM},
		{ "-extension_bitfield_type",  0,      OPTID_BIT_TYPE},
		{ "-cpp_comment",     0,   OPTID_CPPCOMMENT},
		{ "-cpp_out_result",    0,    OPTID_CPPRESULT},
		{ "-src_name_macro",    0,    OPTID_SRC_MACRO},
		{ "-func_name_macro",    0,    OPTID_FUNCTION_MACRO},
		{ "-max_alignment",     1,   OPTID_MAX_ALIGNMENT},
		{ "-bitbyte_new_alignment",  0,      OPTID_BITBYTE_NEW},
		{ "-bytebit_new_alignment",   0,     OPTID_BYTEBIT_NEW},
		{ "-bitbit_size_alignment",    0,    OPTID_BITBIT_BYSIZE},
		{ "-bit_to_divide",     0,   OPTID_DIVIDE_BIT},
		{ "-bit_zero_self",     0,   OPTID_ZEROBIT},
		{ "-bitbit_arrange_bysize",  0,      OPTID_BITBIT_ARRAGNE},
		{ "-pointersize",      1,  OPTID_POINTERSIZE},
		{ "-near_pointersize",   1,     OPTID_NEAR_POINTERSIZE},
		{ "-far_pointersize",     1,   OPTID_FAR_POINTERSIZE},
		{ "-shortsize",   1,     OPTID_SHORTSIZE},
		{ "-intsize",     1,   OPTID_INTSIZE},
		{ "-longsize",    1,    OPTID_LONGSIZE},
		{ "-floatsize",     1,   OPTID_FLOATSIZE},
		{ "-doublesize",      1,  OPTID_DBLSZIE},
		{ "-longdoublesize",    1,    OPTID_LONGDBLSIZE},
		{ "-buildinfunction",    1,     OPTID_BUILDINFUNC },
		{ "-I",  1, OPTID_I_SYM },
		{ "-Iu", 1, OPTID_I_USER },
		{ "-D", 1, OPTID_DMACRO },
		{ "-U", 1, OPTID_UMACRO },
		{ "-N", 1, OPTID_NMACRO },
		{ "-C90", 0, OPTID_C90 },
		{ "-C99", 0, OPTID_C99 },
		{ "-GNU", 0, OPTID_GNU },
		{ NULL, OPTID_NONE }
};

static AST gblCurrTranslationUnit = 0;
/******************************************************************
* 関 数 名 : CCoreStart
* 機    能 : 機能モジュールを初期化
* 引    数 : なし
* 戻 り 値 : S4
* 	　　　:１．　正常終了時：	COEXIT_SUCCESS
* 　　　　　 ：２．　致命エラー：	COEXIT_FATAL
* 詳細内容 :
*******************************************************************/
S4 DLL_EXPORT CCoreStart( VOID )
{
	COptionInfoInit();

	CCodeScopeInit();
	/*debug,12/10/16,S*/
	CFileIndexInit();
	/*debug,12/10/16,E*/

	CDirectiveInfoInit();
	CMacroInfoInit();
	CRepListTokenInit();
	CPPCondExpInit();
	CPPTokenListInit();
	CPPCondExpKindInit();
	CPPPostfixOpKindInit();
	CPPUnaryOpKindInit();
	CPPMultiOpKindInit();
	CPPAdditiveOpKindInit();
	CPPShiftOpKindInit();
	CPPRelationalOpKindInit();
	CPPEqualityOpKindInit();
	CPPAssignOpKindInit();

	CDeclarationInit();
	CTypeSpecifierInit();
	CDeclaratorInit();
	CStatementInit();
	CExpressionInit();
	CExpressionOpKindInit();
	CPostfixOpKindInit();
	CUnaryOpKindInit();
	CMultiOpKindInit();
	CAdditiveOpKindInit();
	CShiftOpKindInit();
	CRelationalOpKindInit();
	CEqualityOpKindInit();
	CConditionOpKindInit();
	CAssignOpKindInit();
	CTypeInfoInit();
	CSymbolInit();
	CValueInfoInit();
	CUniteChainInit();
	CTranslationUnitInit();
	CStringsInit();
	CLinkageInit();
	CDesignationInit();
	CInitializerInit();
//	LinkTranslationUnitInit();
	LinkStringsInit();
	LinkTypeInfoInit();
	LinkMemberInit();
	LinkConstantInit();
	LinkGblLinkageInit();
	LinkVariableInit();
	LinkFunctionInit();
	LinkCommandListInit();
	LinkOperandInit();
	TraceCmdListMetaDataInit();
	TracePathInfoInit();
	TraceLoopInfoInit();
	return COEXIT_SUCCESS;
}
EXTERNAL_SYMBOL( CCoreStart );
/******************************************************************
* 関 数 名 : CCoreTerminate
* 機    能 : 機能モジュールを終了
* 引    数 :　なし
* 戻 り 値 : なし
* 詳細内容 :
*******************************************************************/
VOID DLL_EXPORT CCoreTerminate( VOID )
{
	TblClear_Terminate( );
}
PSZ CCoreGetOptKey( U2 u2OptID ){
	int i;
	for( i = 0; stOptionKey[i].pszKey != NULL; i++  )
	{
		if( stOptionKey[i].u2Id == u2OptID )
		{
			return stOptionKey[i].pszKey;
		}
	}
	return NULL;
}
EXTERNAL_SYMBOL( CCoreTerminate );
S4 DLL_EXPORT CCoreAddOptByString( PSZ pszOptKey ){
	S4  i;
	if( str_length( pszOptKey ) == 0 )
	{
		return COEXIT_SUCCESS;
	}

	for( i = 0; stOptionKey[i].pszKey != NULL; i++  )
	{
		if( strncmp( stOptionKey[i].pszKey, pszOptKey, strlen( stOptionKey[i].pszKey ) ) == 0 )
		{
			return CCoreAddOpt( stOptionKey[i].pszKey, &pszOptKey[strlen( stOptionKey[i].pszKey )]);
		}
	}
	CCoreThrowWarning( CPP_OPT_WRONG, 0, pszOptKey, NULL );
	return COEXIT_SUCCESS;
}
EXTERNAL_SYMBOL( CCoreAddOptByString );
EXTERNAL_SYMBOL( CCoreAddOpt );
/************************************************************************/
/* 関 数 名 : CCoreAddOpt											*/
/* 機    能 :															*/
/* 引 き 数 : 	pszOptKey	オプションのキーワード						*/
/*			pszOptPrm	オプションのパラメータ。　　　　　　 			*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了							*/
/*              COEXIT_FATAL        異常終了                            */
/* 詳細内容 : 															*/
/************************************************************************/
S4 DLL_EXPORT CCoreAddOpt( PSZ pszOptKey, PSZ pszOptPrm )
{
	S4  i;
	U2 u2OptID = OPTID_NONE;
	BOOL bRet;
	AST  astMax;
	if( str_length( pszOptKey ) == 0 )
	{
		return COEXIT_SUCCESS;
	}

	for( i = 0; stOptionKey[i].pszKey != NULL; i++  )
	{
		if( strcmp( stOptionKey[i].pszKey, pszOptKey ) == 0 )
		{
			u2OptID = stOptionKey[i].u2Id;
			break;
		}
	}
	if( u2OptID == OPTID_NONE )
	{
		CCoreThrowWarning( CPP_OPT_WRONG, 0, pszOptKey, NULL );
		return COEXIT_SUCCESS;
	}
	if( str_length( pszOptPrm ) == 0 )
	{
		if( stOptionKey[i].hasParam != 0 ){
			 CCoreThrowWarning( CPP_OPT_SHOULD_HAS_PARAM, 0, pszOptKey, NULL );
		}
	}
	bRet = stCoreOptAccess.alloc(1);
	if(bRet == FALSE)
	{
		return( COEXIT_FATAL ) ;
	}
	astMax = stCoreOptAccess.getMax();
	stCoreOptAccess.optId.set( astMax, u2OptID );

	if( str_length( pszOptPrm ) != 0 )
	{
		if( stOptionKey[i].hasParam == 0 ){
			 CCoreThrowWarning( CPP_OPT_SHOULD_HAS_NOPARAM, 0, pszOptKey, NULL );
		}else{
			stCoreOptAccess.strValue.set( astMax, pszOptPrm );
		}
	}
	return COEXIT_SUCCESS;
}

EXTERNAL_SYMBOL( CCoreCC );
/******************************************************************
* 関 数 名 : CCoreCC
* 機    能 : 構文解析
* 引    数 : PSZ pszSrc	：		ソースファイルのパス名
* 		: BOOL  bCompile：	bCompileはTRUEであるのみ、構文解析を行う
* 戻 り 値 : S4
* 	　　　:１．　正常終了時：		COEXIT_SUCCESS
* 　　　　　 ：２．　警告	：			COEXIT_WARNING
* 　　　　　 ：３．　コンパイルエラー：	COEXIT_ERROR
* 　　　　　 ：４．　致命エラー：		COEXIT_FATAL
* 　　　　　 ：５．　初期化していない：	COEXIT_NOTINIT
* 詳細内容 :
*******************************************************************/
S4 DLL_EXPORT CCoreCC( PSZ pszSrc,  BOOL bCompile )
{
	S4   nRet       = COEXIT_SUCCESS ;
	S4   nRetVal    = 0 ;

	MpuInit(stCoreEnvInfo.ulCplKind );
	/* テーブルKIND_TRANSLATIONUNITに1行追加 */
	FATAL_ON_FALSE(stCoreTranslationUnitAccess.alloc(1));

	/* テーブルKIND_TRANSLATIONUNITの行の総数を「翻訳単位情報」に設定 */
	gblCurrTranslationUnit = stCoreTranslationUnitAccess.getMax();
	/*プリプロセッサを実行*/
    nRet = CPreprocessing(pszSrc) ;
	/*コンパイラを実行*/
	if(  (  ( nRet == COEXIT_SUCCESS )
	      ||( nRet == COEXIT_WARNING ) )
	   &&( bCompile == TRUE ) )
	{
		nRetVal = CSyntaxProcessing() ;
		if(nRetVal > nRet)
		{
			nRet = nRetVal ;
		}
    }
	stCCLinkageAccess.clearRoot();
	return ( nRet );
}
VOID DLL_EXPORT ClearCoreCCResult( VOID ){
	ClearTUPreprocessingResult();
	ClearTUSyntaxProcessingResult();
}
EXTERNAL_SYMBOL( ClearCoreCCResult );
U4 DLL_EXPORT CCoreGetMemoryMaxSize( VOID ){
	return MemGetMaxSize();
}
EXTERNAL_SYMBOL( CCoreGetMemoryMaxSize );
U4 DLL_EXPORT CCoreGetMemoryCurrentSize( VOID ){
	return MemGetUsefulSize();
}
EXTERNAL_SYMBOL( CCoreGetMemoryCurrentSize );
VOID DLL_EXPORT CCoreReleaseUnusedMem( VOID ){
	MemReleaseUnusedMem();
}
EXTERNAL_SYMBOL( CCoreReleaseUnusedMem );
AST  CCoreGetCurrTranslatioUnit( VOID ){
	return gblCurrTranslationUnit;
}
S4  CCoreThrowWarning( U4 code, AST astCodeScp, PSZ pszParameter, ALERT_MSG_PARAM * value ){
	return AlertThrowWaring( code, astCodeScp, pszParameter, value );
}
/**********************[end of file]*****************/
